﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Reflection;
using FilterData;


namespace BYClient
{
    public class YClient
    {
        public event EventHandler<EventReceiveMessareArgs> OnReceiveData;
        FilterDataManager FdataManager;
        Socket Client;
        string hostname;
        byte[] data = new byte[1024];
        byte[] ResultDataFilter;
        byte[] SendDataFilter;
        int port;
        public System.Windows.Controls.UserControl win;
        public YClient()
        {
            Client = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            FdataManager = new FilterDataManager();
        }
        public void Connect(string hostname,int port)
        {
            Client.Connect(hostname, port);           
            
            this.hostname = hostname;
            this.port = port;
            if (!Client.Connected)
            {
                Console.WriteLine("Khong tim thay host va port tuong ung");
                return;
            }          
           
            Client.BeginReceive(data, 0, 1, SocketFlags.None, new AsyncCallback(OnSizeReceive), null);
        }

       
        void OnSizeReceive(IAsyncResult ar)
        {
            try
            {
                if (!ar.IsCompleted)
                {
                    System.Windows.MessageBox.Show("Send No Complete");
                    return;
                }
                Client.EndReceive(ar);
                byte[] received = new byte[] { data[0],data[1] };
                SumSizeReceive = (int)BitConverter.ToInt16(received,0) ;
                if (SumSizeReceive > 0)
                    Client.BeginReceive(data, 1, SumSizeReceive, SocketFlags.None, new AsyncCallback(OnReceive), null);
                else
                    Client.BeginReceive(data, 0, 1, SocketFlags.None, new AsyncCallback(OnSizeReceive), null);
            }
            catch (System.Exception e)
            {
            	
            }
        }

        int SumSizeReceive = 0;
        int SizeReceived = 0;
        
        void OnReceive(IAsyncResult ar)
        {
            try
            {
                if (!ar.IsCompleted)
                {
                    System.Windows.MessageBox.Show("Error Receive");
                    return;
                }
                SocketError error;
                int i = Client.EndReceive(ar,out error);
                if(i < 1)
                {
                    System.Windows.MessageBox.Show("Error Receive");
                    return;
                }
                SizeReceived += i;
                if (SizeReceived < SumSizeReceive)
                {
                    Client.BeginReceive(data, SizeReceived + 1, SumSizeReceive - SizeReceived, SocketFlags.None, new AsyncCallback(OnReceive), null);
                }
                else
                {
                    ProcessReceiveFullData();
                    ResetSumReceive();
                    Client.BeginReceive(data, 0, 1, SocketFlags.None, new AsyncCallback(OnSizeReceive), null);
                }
                    
                
                
            }
            catch (System.Exception e)
            {
                System.Windows.MessageBox.Show(e.Message);
            }
        }
        void ResetSumReceive()
        {
            SumSizeReceive = 0;
            SizeReceived = 0;
            data = new byte[1024];
        }
        void ProcessReceiveFullData()
        {
            ResultDataFilter = FdataManager.ProcessDataReceive(data);          
            win.Dispatcher.Invoke(new Action(this.invoke));       
        }
        private void invoke()
        {
            if (OnReceiveData != null)
                OnReceiveData(this, new EventReceiveMessareArgs(ResultDataFilter));

        }
       

        public void SendMessage(byte[] message)
        {
            SendDataFilter = FdataManager.ProcessDataSend(message);
            Client.BeginSend(SendDataFilter, 0, SendDataFilter.Length, SocketFlags.None, new AsyncCallback(OnSend), null);                    
        }
        void OnSend(IAsyncResult ar)
        {
            try
            {
                if (!ar.IsCompleted)
                    System.Windows.MessageBox.Show("Send No Complete");
                Client.EndSend(ar);               
            }
            catch (System.Exception e)
            {
                System.Windows.MessageBox.Show(e.Message);
            }
        }

        
    }
    
}
